const express = require('express')
const router = express.Router()
const multer = require('multer')
const resizeImg = require('resize-img');
const userDB = require('../../db/user')
const msgDB = require('../../db/msg')
const linkDB = require('../../db/link')
const articleDB = require('../../db/article')
const mottoDB = require('../../db/motto')
const fs = require('fs')
const path = require('path')

// 鉴权
router.use((req, res, next) => {
  if(!req.session.userInfo){
    // console.log('用户未登录');
    return res.send({
      code: 7,
      msg: '用户未登录'
    })
  }

  if (!req.session.userInfo.isAdmin) {
    // console.log('非管理员账号，没有权限操作');
    return res.send({
      code: 7,
      msg: "非管理员账号，没有权限操作"
    })
  }
  next()
})

// 文章图片：multer上传保存至硬盘
const storage = multer.diskStorage({
  // 文件存放地址
  destination: function (req, file, cb) {
    let dir = path.join(__dirname, '../../public/files/img/article') //图片存储的目录
    //判断目录是否存在，没有则创建
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, {recursive: true});
    }
    //dir就是上传文件存放的目录
    cb(null, dir);
  },
  // 文件名命名
  filename: function (req, file, cb) {
    // const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
    // cb(null, file.fieldname + '-' + uniqueSuffix)
    let fileformat = (file.originalname).split('.')
    let fileName = fileformat[0] + "-" + Date.now().toString(32) + '.'+ fileformat[fileformat.length-1]
    req.fileName = fileName
    cb(null, fileName)
  }
})

// 文章封面图片：multer上传保存至硬盘
const storageCover = multer.diskStorage({
  // 文件存放地址
  destination: function (req, file, cb) {
    let dir = path.join(__dirname, '../../public/files/img/article/cover') //图片存储的目录
    //判断目录是否存在，没有则创建
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, {recursive: true});
    }
    //dir就是上传文件存放的目录
    cb(null, dir);
  },
  // 文件名命名
  filename: function (req, file, cb) {
    // const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
    // cb(null, file.fieldname + '-' + uniqueSuffix)
    let fileformat = (file.originalname).split('.')
    let fileName = fileformat[0] + "-" + Date.now().toString(32) + '.'+ fileformat[fileformat.length-1]
    req.fileName = fileName
    cb(null, fileName)
  }
})

const upload = multer({ storage: storage }).single("articleImg")
const uploadCover = multer({ storage: storageCover }).single("file")

// 获取经典
router.post('/mottoList', async (req, res) => {
  let data = await mottoDB.find({})
  res.send({
    code: 0,
    msg: '成功获取经典列表',
    data
  })
})

// 发布经典
router.post('/publishMotto', async (req, res) => {
  let {motto, mottoRef, classify} = req.body
  if(!motto || !mottoRef || !classify){
    return res.send({
      code: 1,
      msg: "数据格式错误"
    })
  }

  let doc = await mottoDB.findOne({motto})
  if(doc){
    return res.send({
      code: 2,
      msg: '该经典数据库已存在'
    })
  }

  await mottoDB.create({motto, mottoRef, classify})

  res.send({
    code: 0,
    msg: '经典发布成功'
  })
})

// 设置经典状态：发布or下架
router.post('/offMotto', async (req, res) => {
  let {_id, status} = req.body

  let doc = await mottoDB.findById(_id)
  if(!doc){
    return res.send({
      code: 1,
      msg: '经典不存在'
    })
  }

  try{
    await mottoDB.findByIdAndUpdate(_id, {$set: {status}})

    let message = status === false ? "经典已下架" : "经典已发布"
    res.send({
      code: 0,
      msg: message
    })
  }catch(e){
    res.send({
      code: 2,
      msg: e
    })
  }
})

// 删除经典
router.post('/mottoDelete', async (req, res) => {
  let {_id} = req.body

  let doc = await mottoDB.findById(_id)
  if(!doc){
    return res.send({
      code: 1,
      msg: '经典不存在'
    })
  }

  await mottoDB.findByIdAndDelete(_id)

  return res.send({
    code: 0,
    msg: '经典已删除'
  })
})

// 上传文章封面图片
router.post('/uploadCover', async (req, res) => {
  uploadCover(req, res, async (err) => {
    if (err instanceof multer.MulterError) {
      console.log('A Multer error occurred when uploading.');
      return res.send({
        code: 1,
        msg: 'A Multer error occurred when uploading.'
      })
    } else if (err) {
      console.log('An unknown error occurred when uploading.');
      return res.send({
        code: 2,
        msg: 'An unknown error occurred when uploading.'
      })
    }
    
    let dir = path.join(__dirname, '../../public/files/img/article/cover/')
    let fileformat = (req.fileName).split('.')
    let defaultImg = `${dir}${req.fileName}`
    let cutImg = `${dir}${fileformat[0]}_pr.${fileformat[1]}`
    // console.log(defaultImg)
    // console.log(cutImg)
    // 生成封面缩略图
    let image = await resizeImg(fs.readFileSync(defaultImg), {
      width: 20,
      height: 20
    })
    fs.writeFileSync(cutImg, image)

    res.send({
      code: 0,
      msg: '文章封面上传成功',
      data: {
        url: req.fileName,
        coverPrUrl: `${fileformat[0]}_pr.${fileformat[1]}`
      }
    })
  })
})

// 上传文章图片（wangEditor编辑器用）
router.post('/uploadImg', async (req, res) => {
  upload(req, res, async (err) => {
    if (err instanceof multer.MulterError) {
      console.log('A Multer error occurred when uploading.');
      return res.send({
        code: 1,
        msg: 'A Multer error occurred when uploading.'
      })
    } else if (err) {
      console.log('An unknown error occurred when uploading.');
      return res.send({
        code: 2,
        msg: 'An unknown error occurred when uploading.'
      })
    }
    
    let fileName = (req.fileName).split('.')[0]
    res.send({
      code: 0,
      msg: '图片上传成功',
      data: {
        url: '/files/img/article/'+ req.fileName,
        name: fileName
      }
    })
  })
})

// 上传文章
router.post('/uploadArticle', async (req, res) => {
  let { title, content, source, classify, cover, coverPr, author, tag, message, share } = req.body
  if (!title || !content || !classify) {
    return res.send({
      code: 1,
      msg: "数据格式错误"
    })
  }

  if(cover === ""){
    cover = '/files/img/article/cover/default.jpg'
    coverPr = '/files/img/article/cover/default_pr.jpg'
  }else{
    cover = '/files/img/article/cover/'+cover
    coverPr = '/files/img/article/cover/'+coverPr
  }
  //创建数据
  await articleDB.create({
    title,
    content,
    source,
    classify,
    cover,
    coverPr,
    author,
    tag,
    message,
    share
  })

  //返回前端
  res.send({
    code: 0,
    msg: "文章上传完成"
  })
})

// 文章下架/上架
router.post('/offArticle', async (req, res) => {
  let {_id, status} = req.body

  let doc = await articleDB.findById(_id)
  if(!doc){
    return res.send({
      code: 1,
      msg: '文章不存在'
    })
  }

  try{
    await articleDB.findByIdAndUpdate(_id, {$set: {status}})

    let message = status === false ? "文章已下架" : "文章已发布"
    res.send({
      code: 0,
      msg: message
    })
  }catch(e){
    res.send({
      code: 2,
      msg: e
    })
  }
})

// 文章删除
router.post('/articleDelete', async (req, res) => {
  let {_id} = req.body

  let doc = await articleDB.findById(_id)
  if(!doc){
    return res.send({
      code: 1,
      msg: '文章不存在'
    })
  }

  await articleDB.findByIdAndDelete(_id)

  return res.send({
    code: 0,
    msg: '文章已删除'
  })
})

// 删除友链
router.post('/linkDelete', async (req, res) => {
  let {_id} = req.body

  let doc = await linkDB.findById(_id)
  if(!doc){
    return res.send({
      code: 1,
      msg: '友链不存在'
    })
  }

  await linkDB.findByIdAndDelete(_id)

  return res.send({
    code: 0,
    msg: '友链已删除'
  })
})

// 设置友链状态：发布or下架
router.post('/setLinkStatus', async (req, res) => {
  let {_id, status} = req.body

  let doc = await linkDB.findById(_id)
  if(!doc){
    return res.send({
      code: 1,
      msg: '友链不存在'
    })
  }

  try{
    await linkDB.findByIdAndUpdate(_id, {$set: {status}})

    let message = status === false ? "友链已下架" : "友链已发布"
    res.send({
      code: 0,
      msg: message
    })
  }catch(e){
    res.send({
      code: 2,
      msg: e
    })
  }
})

// 友链列表：简单粗暴，直接拿……
router.post('/getLinks', async (req, res) => {
    let data = await linkDB.find({})
    res.send({
      code: 0,
      msg: '成功获取友链列表',
      data
    })
})

// 创建友链信息
router.post('/linkCreate', async (req, res) => {
  let {sitename, site, avatar, introduction} = req.body
  let sitenameReg = /^[^]{2,20}$/
  let siteReg = /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?$/
  let avatarReg = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?/

  if(!sitenameReg.test(sitename) || !siteReg.test(site) || !avatarReg.test(avatar)){
    return res.send({
      code: 1,
      msg: '数据格式错误'
    })
  }

  let doc = await linkDB.findOne({site})
  if(doc){
    return res.send({
      code: 2,
      msg: '该博客已申请过友链，请勿重复提交'
    })
  }

  await linkDB.create({sitename, site, avatar, introduction})

  res.send({
    code: 0,
    msg: '友链信息申请成功'
  })
})

// 获取用户列表
router.post('/allUser', async (req, res) => {
  let data = await userDB
                    .find({}, 
                      {
                        pass: 0, 
                        avatar: 0, 
                        fans: 0, 
                        follows: 0,
                        userSignature: 0
                    })
                    .sort({regDate: -1})

  res.send({
    code: 0,
    msg: '成功获取用户列表',
    data
  })
})

// 用户表操作(管理员和留言权限)
router.post('/setUser', async (req, res) => {
  let {_id, isAdmin, msgPermissions} = req.body
  let doc = await userDB.findById({_id})
  if(!doc){
    return res.send({
      code: 1,
      msg: '用户不存在'
    })
  }

  try{
    await userDB.findByIdAndUpdate(_id, {$set: {isAdmin, msgPermissions}})

    res.send({
      code: 0,
      msg: '更新成功'
    })
  }catch(e){
    res.send({
      code: 2,
      msg: e
    })
  }  
})

// 获取留言列表
router.post('/msgList', async (req, res) => {
  let {curPage, pageSize} = req.body
  let data = await msgDB
                    .find({}, {visitorAvatar: 0, isVisitor: 0, email: 0, siteAdress: 0, likes: 0, 'children.likes': 0, 'children.replyUser': 0})
                    .skip(curPage * pageSize)
                    .limit(pageSize)
                    .sort({date: -1})
                    .populate("user", {pass: 0, avatar: 0, regDate: 0, isAdmin: 0, msgPermissions: 0, userSignature: 0, fans: 0, follows: 0})
                    .populate("children.user", {pass: 0, avatar: 0, regDate: 0, isAdmin: 0, msgPermissions: 0, userSignature: 0, fans: 0, follows: 0})                    

  let totalCount = 0;
  await msgDB.find().countDocuments((err, result)=>{
    totalCount = result
    // console.log("find:", result);
  })
  res.send({
    code: 0,
    msg: '获取留言成功',
    data:{
      totalCount,
      list: data
    }
  })
})

// 获取留言投诉列表
router.post('/msgReportList', async(req, res) => {
  let {curPage, pageSize} = req.body
  let data = await msgDB
                    .find({reports : {$exists:true}, $where:'this.reports.length>0'}, {visitorAvatar: 0, isVisitor: 0, email: 0, siteAdress: 0, likes: 0, 'children.likes': 0, 'children.replyUser': 0})
                    .skip(curPage * pageSize)
                    .limit(pageSize)
                    .sort({date: -1})
                    .populate("user", {pass: 0, avatar: 0, regDate: 0, isAdmin: 0, msgPermissions: 0, userSignature: 0, fans: 0, follows: 0})
                    .populate("children.user", {pass: 0, avatar: 0, regDate: 0, isAdmin: 0, msgPermissions: 0, userSignature: 0, fans: 0, follows: 0})                    

  // console.log(data)
  // 返回客户端
  res.send({
    code: 0,
    msg: '获取留言反馈列表成功',
    data
  })
})

// 留言表操作(屏蔽，置顶)
router.post('/setMsg', async (req, res) => {
  let {_id, childId, isShield, isTop} = req.body

  let doc
  if(childId){
    doc = (await msgDB.findById(_id)).children.id(childId)
  }else{
    doc = await msgDB.findById(_id)
  }
  
  if(!doc){
    return res.send({
      code: 1,
      msg: '留言不存在'
    })
  }

  try{
    if(childId){
      // 子留言没有isTop字段（置顶）
      await msgDB.updateOne(
        { _id, 'children._id': childId }, 
        { $set:{ 'children.$.isShield': isShield} }
      )
    }else{
      await msgDB.updateOne(
        { _id },
        { $set: { isShield, isTop } }
      )
    }
    res.send({
      code: 0,
      msg: '更新成功'
    })
  }catch(e){
    res.send({
      code: 2,
      msg: e
    })
  }
})

// 删除单条留言
router.post('/deleteSingleMsg', async (req, res) => {
  let {_id, childId} = req.body
  let doc
  if(childId){
    doc = (await msgDB.findById(_id)).children.id(childId)
  }else{
    doc = await msgDB.findById(_id)
  }
  
  if(!doc){
    return res.send({
      code: 1,
      msg: '留言不存在'
    })
  }

  try{

    if(childId){
      // 删除子留言
      await msgDB.findByIdAndUpdate(_id, {
        '$pull': {
          'children':{ '_id': childId }
        }
      })
    }else{
      await msgDB.findByIdAndDelete(_id)
    }

    res.send({
      code: 0,
      msg: '删除成功'
    })
  }catch(e){
    res.send({
      code: 2,
      msg: e
    })
  }
})

module.exports = router